בעזרת ה-Media Session API, אפשר להתאים אישית את ההתראות של המדיה ואת פקדי ההפעלה

איך משתלבים עם מפתחות מדיה בחומרה, מתאימים אישית את ההתראות על מדיה ועוד.

François Beaufort
François Beaufort

כדי לאפשר למשתמשים לדעת מה מופעל כרגע בדפדפן שלהם ולשלוט בו בלי לחזור לדף שבו הוא הופעל, הוספנו את Media Session API. הוא מאפשר למפתחי אתרים להתאים אישית את החוויה הזו באמצעות מטא-נתונים בהתראות מותאמות אישית לגבי מדיה, אירועי מדיה כמו הפעלה, השהיה, דילוג, שינוי טראק ואירועים של כנס וידאו כמו השבתה/הפעלה של המיקרופון, הפעלה/כיבוי של המצלמה וסיום השיחה. ההתאמות האישיות האלה זמינות בכמה הקשרים, כולל מרכזי מדיה במחשב, התראות על מדיה בנייד ואפילו במכשירים לבישים. במאמר הזה נתאר את ההתאמות האישיות האלה.

צילומי מסך של הקשרים של סשן מדיה.
Media hub במחשב, התראות על מדיה בנייד ומכשיר לביש.

מידע על Media Session API

ל-Media session API יש כמה יתרונות ויכולות:

  • יש תמיכה במפתחות מדיה לחומרה.
  • אפשר להתאים אישית את ההתראות על מדיה בנייד, במחשב ובמכשיר נייד משולב.
  • מרכז המדיה זמין במחשב.
  • פקדי המדיה במסך הנעילה זמינים ב-ChromeOS ובמכשירים ניידים.
  • הפקדים של חלון התמונה בתוך תמונה זמינים להפעלת אודיו, לשיחות וידאו ולהצגת שקפים.
  • השילוב עם Assistant זמין בנייד.

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 82.
  • Safari: 15.

Source

ריכזנו כאן כמה דוגמאות שיעזרו להמחיש את הנקודות האלה.

דוגמה 1: אם משתמשים לוחצים על מקש המדיה 'טראק הבא' במקלדת, מפתחי האתר יכולים לטפל בפעולה הזו של המשתמש גם אם הדפדפן נמצא בחזית וגם אם הוא ברקע.

דוגמה 2: אם משתמשים מקשיבים לפודקאסט באינטרנט בזמן שמסך המכשיר נעול, הם עדיין יכולים ללחוץ על סמל ה'דילוג לאחור' באמצעי הבקרה של המדיה במסך הנעילה, כדי שמפתחי האתרים יוכלו להזיז את זמן ההפעלה לאחור בכמה שניות.

דוגמה 3: אם למשתמשים יש כרטיסיות עם אודיו שפועל, הם יכולים להפסיק בקלות את ההפעלה ממרכז המדיה במחשב, כדי שמפתחי האתרים יוכלו למחוק את המצב שלהם.

דוגמה 4: אם משתמשים נמצאים בשיחת וידאו, הם יכולים ללחוץ על לחצן החלפת המצב של המיקרופון בחלון התצוגה בחלון כדי למנוע מהאתר לקבל נתוני מיקרופון.

כל זה מתבצע באמצעות שני ממשקים שונים: הממשק של MediaSession והממשק של MediaMetadata. האפשרות הראשונה מאפשרת למשתמשים לשלוט במה שמופעל. השני הוא איך אומרים ל-MediaSession מה צריך לשלוט בו.

כדי להמחיש, בתמונה הבאה אפשר לראות איך הממשקים האלה קשורים לפקדי מדיה ספציפיים, במקרה הזה התראה על מדיה בנייד.

איור של ממשקי Media Session.
המבנה של התראת מדיה בנייד.

מודיע למשתמשים מה מושמע

כשבאתר מסוים מופעל אודיו או וידאו, המשתמשים מקבלים התראות מדיה באופן אוטומטי בחלונית ההתראות בנייד או במרכז המדיה במחשב. הדפדפן עושה כמיטב יכולתו כדי להציג מידע מתאים, באמצעות שם המסמך ותמונת הסמל הגדולה ביותר שהוא יכול למצוא. באמצעות Media Session API אפשר להתאים אישית את התראת המדיה באמצעות מטא-נתונים עשירים יותר של המדיה, כמו הכותרת, שם האומן, שם האלבום וגרפיקה, כפי שמתואר בהמשך.

Chrome מבקש 'ריכוז אודיו מלא' כדי להציג התראות על מדיה רק כשאורך המדיה הוא לפחות 5 שניות. כך תוכלו לוודא שצלילים מקריים, כמו צלצולים, לא יוצגו התראות.

// After media (video or audio) starts playing
await document.querySelector("video").play();

if ("mediaSession" in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    artist: 'Rick Astley',
    album: 'Whenever You Need Somebody',
    artwork: [
      { src: 'https://via.placeholder.com/96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
      { src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
      { src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  });

  // TODO: Update playback state.
}

כשההפעלה מסתיימת, אין צורך 'לשחרר' את סשן המדיה כי ההתראה תיעלם באופן אוטומטי. עם זאת, חשוב לזכור ש-navigator.mediaSession.metadata ישמש כשההפעלה הבאה תתחיל. לכן חשוב לעדכן אותו כשמקור ההפעלה של המדיה משתנה, כדי לוודא שמופיע מידע רלוונטי בהתראה על המדיה.

יש כמה דברים שכדאי לזכור לגבי המטא-נתונים של המדיה.

  • מערך הגרפיקה של ההתראות תומך בכתובות URL של blob ובכתובות URL של נתונים.
  • אם לא מוגדרת גרפיקה ויש תמונה של סמל (שצוינה באמצעות <link rel=icon>) בגודל הרצוי, המערכת תשתמש בה בהתראות על מדיה.
  • גודל היעד של גרפיקה של התראות ב-Chrome ל-Android הוא 512x512. במכשירים בסיסיים, הערך הוא 256x256.
  • המאפיין title של רכיב ה-HTML של המדיה משמש בווידג'ט 'השיר או הסרטון שמתנגן עכשיו' ב-macOS.
  • אם משאב המדיה מוטמע (לדוגמה ב-iframe), צריך להגדיר את המידע של Media Session API מההקשר המוטמע. קטע הקוד לדוגמה מופיע בהמשך.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

אפשר גם להוסיף למטא-נתונים של המדיה פרטים ספציפיים של פרקים, כמו שם הקטע, חותמת הזמן שלו ותמונת מסך. כך המשתמשים יכולים לנווט בתוכן של המדיה.

navigator.mediaSession.metadata = new MediaMetadata({
  // title, artist, album, artwork, ...
  chapterInfo: [{
    title: 'Chapter 1',
    startTime: 0,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }, {
    title: 'Chapter 2',
    startTime: 42,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }]
});
פרטי הפרק שמוצגים בהתראה על מדיה ב-ChromeOS.
התראה על מדיה עם פרקים ב-ChromeOS.

איך מאפשרים למשתמשים לשלוט בתוכן המושמע

פעולה בסשן מדיה היא פעולה (לדוגמה, 'הפעלה' או 'השהיה') שאתר יכול לטפל בה עבור משתמשים כשהם מבצעים אינטראקציה עם הפעלת המדיה הנוכחית. פעולות דומות לאירועים ופועלות באופן דומה. בדומה לאירועים, כדי להטמיע פעולות צריך להגדיר גורמים מטפלים באובייקט מתאים, במקרה הזה מופע של MediaSession. חלק מהפעולות מופעלות כשמשתמשים לוחצים על לחצנים באוזניות, במכשיר מרוחק אחר, במקלדת או מבצעים אינטראקציה עם התראה על מדיה.

צילום מסך של התראת מדיה ב-Windows 10.
התראת מדיה בהתאמה אישית ב-Windows 10.

יכול להיות שחלק מהפעולות בסשן המדיה לא נתמכות, לכן מומלץ להשתמש בבלוק try…catch כשמגדירים אותן.

const actionHandlers = [
  ['play',          () => { /* ... */ }],
  ['pause',         () => { /* ... */ }],
  ['previoustrack', () => { /* ... */ }],
  ['nexttrack',     () => { /* ... */ }],
  ['stop',          () => { /* ... */ }],
  ['seekbackward',  (details) => { /* ... */ }],
  ['seekforward',   (details) => { /* ... */ }],
  ['seekto',        (details) => { /* ... */ }],
  /* Video conferencing actions */
  ['togglemicrophone', () => { /* ... */ }],
  ['togglecamera',     () => { /* ... */ }],
  ['hangup',           () => { /* ... */ }],
  /* Presenting slides actions */
  ['previousslide', () => { /* ... */ }],
  ['nextslide',     () => { /* ... */ }],
];

for (const [action, handler] of actionHandlers) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch (error) {
    console.log(`The media session action "${action}" is not supported yet.`);
  }
}

כדי לבטל את ההגדרה של בורר הפעולות של סשן המדיה, פשוט מגדירים אותו כ-null.

try {
  // Unset the "nexttrack" action handler at the end of a playlist.
  navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
  console.log(`The media session action "nexttrack" is not supported yet.`);
}

אחרי ההגדרה, בוררי הפעולות של סשן המדיה ימשיכו לפעול במהלך הפעלות המדיה. זה דומה לדפוס של מאזין לאירועים, אלא שבטיפול באירוע הדפדפן מפסיק לבצע את התנהגות ברירת המחדל שלו ומשתמש בכך כאות לכך שהאתר תומך בפעולה של המדיה. לכן, פקדי הפעולה של המדיה לא יוצגו אלא אם הוגדר טיפול הפעולות המתאים.

צילום מסך של הווידג&#39;ט &#39;התכנים המוצגים כרגע&#39; ב-macOS Big Sur.
הווידג'ט 'המוזיקה שמתנגנת עכשיו' ב-macOS Big Sur.

הפעלה / השהיה

הפעולה "play" מציינת שהמשתמש רוצה להמשיך את הפעלת המדיה, ואילו הפעולה "pause" מציינת רצון להשהות אותה באופן זמני.

סמל ההפעלה/השהיה תמיד מוצג בהתראה על מדיה, והדפדפן מטפל באופן אוטומטי באירועי המדיה הקשורים. כדי לשנות את התנהגות ברירת המחדל שלהן, צריך לטפל בפעולות המדיה 'הפעלה' ו'השהיה' כפי שמתואר בהמשך.

לדוגמה, יכול להיות שהדפדפן יקבע שאתר לא מפעיל מדיה בזמן דילוג או טעינת תוכן. במקרה כזה, כדי לוודא שהממשק של האתר יישאר מסונכרן עם אמצעי הבקרה של התראות המדיה, צריך לשנות את הערך של navigator.mediaSession.playbackState ל-"playing" או ל-"paused".

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('play', async () => {
  // Resume playback
  await video.play();
});

navigator.mediaSession.setActionHandler('pause', () => {
  // Pause active playback
  video.pause();
});

video.addEventListener('play', () => {
  navigator.mediaSession.playbackState = 'playing';
});

video.addEventListener('pause', () => {
  navigator.mediaSession.playbackState = 'paused';
});

הטראק הקודם

הפעולה "previoustrack" מציינת שהמשתמש רוצה להתחיל את ההפעלה הנוכחית של המדיה מההתחלה, אם יש מושג של התחלה בהפעלת המדיה, או לעבור לפריט הקודם בפלייליסט, אם יש מושג של פלייליסט בהפעלת המדיה.

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

הטראק הבא

הפעולה "nexttrack" מציינת שהמשתמש רוצה להעביר את הפעלת המדיה לפריט הבא בפלייליסט, אם הפעלת המדיה כוללת פלייליסט.

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

עצירה

הפעולה "stop" מציינת שהמשתמש רוצה להפסיק את הפעלת המדיה ולמחוק את המצב, אם רלוונטי.

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

דילוג לאחור / קדימה

הפעולה "seekbackward" מציינת שהמשתמש רוצה להזיז את זמן ההפעלה של המדיה אחורה בפרק זמן קצר, ואילו הפעולה "seekforward" מציינת רצון להזיז את זמן ההפעלה של המדיה קדימה בפרק זמן קצר. בשני המקרים, תקופה קצרה היא כמה שניות.

הערך של seekOffset שסופק בטיפול הפעולה הוא משך הזמן בשניות שצריך להזיז את זמן ההפעלה של המדיה. אם לא מציינים את הערך (לדוגמה undefined), צריך להשתמש בערך הגיוני (לדוגמה 10-30 שניות).

const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.max(video.currentTime - skipTime, 0);
  // TODO: Update playback state.
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
  // TODO: Update playback state.
});

דילוג לזמן ספציפי

הפעולה "seekto" מציינת שהמשתמש רוצה להעביר את הזמן של הפעלת המדיה לשעה ספציפית.

הערך של seekTime שסופק בטיפול הפעולה הוא הזמן בשניות שאליו צריך להעביר את זמן ההפעלה של המדיה.

הערך הבוליאני fastSeek שסופק בטיפול הפעולה הוא true אם הפעולה נקראת כמה פעמים כחלק מרצף, וזו לא הקריאה האחרונה ברצף הזה.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    // Only use fast seek if supported.
    video.fastSeek(details.seekTime);
    return;
  }
  video.currentTime = details.seekTime;
  // TODO: Update playback state.
});

הגדרת מיקום ההפעלה

כדי להציג בצורה מדויקת את מיקום ההפעלה של המדיה בהתראה, פשוט מגדירים את מצב המיקום בזמן המתאים, כפי שמתואר בהמשך. מצב המיקום הוא שילוב של קצב ההפעלה של המדיה, משך הזמן והשעה הנוכחית.

צילום מסך של פקדי המדיה במסך הנעילה ב-ChromeOS.
אמצעי הבקרה של המדיה במסך הנעילה ב-ChromeOS.

משך הזמן חייב להיות חיובי. המיקום חייב להיות חיובי וקטן מהמשך הזמן. קצב ההפעלה חייב להיות גדול מ-0.

const video = document.querySelector('video');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: video.duration,
      playbackRate: video.playbackRate,
      position: video.currentTime,
    });
  }
}

// When video starts playing, update duration.
await video.play();
updatePositionState();

// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
  /* ... */
  updatePositionState();
});

// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
  updatePositionState();
});

איפוס מצב המיקום קל כמו הגדרתו ל-null.

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

פעולות בשיחות ועידה בווידאו

כשהמשתמש מעביר את שיחת הווידאו לחלון של תמונה בתוך תמונה, יכול להיות שבדפדפן יוצגו לחצני בקרה למיקרופון ולמצלמה ולניתוק השיחה. כשהמשתמשים לוחצים עליהם, האתר מטפל בהם באמצעות הפעולות הבאות של שיתוף המסך. דוגמה לכך מופיעה בדוגמה של שיחת ועידה בווידאו.

צילום מסך של אמצעי הבקרה של שיתוף המסך בחלון מסוג &#39;תמונה בתוך תמונה&#39;.
פקדים של שיחות ועידה בווידאו בחלון 'תמונה בתוך תמונה'.

החלפת מצב מיקרופון

הפעולה "togglemicrophone" מציינת שהמשתמש רוצה להשתיק או לבטל את ההשתקה של המיקרופון. השיטה setMicrophoneActive(isActive) מאפשרת לדפדפן לדעת אם המיקרופון פעיל כרגע באתר.

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

החלפת המצב של המצלמה

הפעולה "togglecamera" מציינת שהמשתמש רוצה להפעיל או להשבית את המצלמה הפעילה. השיטה setCameraActive(isActive) מציינת אם הדפדפן מחשיב את האתר כפעיל.

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

ניתוק

הפעולה "hangup" מציינת שהמשתמש רוצה לסיים שיחה.

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

פעולות של הצגת שקפים

כשהמשתמש מעביר את הצגת השקפים לחלון 'תמונה בתוך תמונה', יכול להיות שבדפדפן יוצגו לחצני שליטה לניווט בין השקפים. כשהמשתמש לוחץ עליהם, האתר מטפל בהם דרך Media Session API. לדוגמה, ראו את הדוגמה להצגת שקפים.

השקף הקודם

הפעולה "previousslide" מציינת שהמשתמש רוצה לחזור לשקופית הקודמת במהלך הצגת השקופיות.

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: not supported.
  • Safari: not supported.

השקף הבא

הפעולה "nextslide" מציינת שהמשתמש רוצה לעבור לשקף הבא במהלך הצגת השקפים.

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: not supported.
  • Safari: not supported.

דוגמאות

כדאי לעיין בדוגמאות ל-Media Session שכוללות את עבודות Blender Foundation ואת עבודותיו של Jan Morgenstern.

הקלטת מסך שממחישה את Media Session API.

משאבים